package com.zlkj.sms.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zlkj.sms.bean.DeviceBean;
import com.zlkj.sms.bean.ResultData;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author lzw
 * @description 系统工具类
 * @date 2021/1/21
 */
@Slf4j
public class Tools {

    /**
     * MD5加密盐值
     */
    public static String ENCRYPT_KEY = "ZLKJ_SOFT_LZW";

    /**
     * 单条记录查询数据返回结果封装
     * @param data
     * @return
     */
    public static ResultData toResult(Object data){
        ResultData result = new ResultData("-1", GnMessage.getFailMsg("01"));
        if(data != null && isEmptyData(data)){
            result.setMsg("暂无符合条件的数据");
        }else if(data != null){
            //成功代码：列表数据code=0，单个数据code=1
            result.setCode(data instanceof List ? "0" : "1");
            result.setMsg(GnMessage.getSuccessMsg("01"));
            result.setData(data);
        }
        return result;
    }

    /**
     * 基本操作返回结果封装
     * @param flag
     * @param gnbj
     * @return
     */
    public static ResultData toResult(boolean flag, String gnbj){
        ResultData result = new ResultData("-1", GnMessage.getFailMsg(gnbj));
        if(flag){
            result.setCode("1");
            result.setMsg(GnMessage.getSuccessMsg(gnbj));
        }
        return result;
    }

    /**
     * 基本操作返回结果封装
     * @param flag
     * @param gnbj
     * @param data
     * @return
     */
    public static ResultData toResult(boolean flag, String gnbj, Object data){
        ResultData result = new ResultData("-1", GnMessage.getFailMsg(gnbj));
        if(flag){
            result.setCode("1");
            result.setMsg(GnMessage.getSuccessMsg(gnbj));
        }
        result.setData(data);
        return result;
    }

    /**
     * 判断数据是否为空
     * @param data
     * @return
     */
    public static boolean isEmptyData(Object data){
        if(data == null){
            return true;
        }else if(data instanceof List && ((List) data).size() == 0){
            return true;
        }
        return false;
    }

    /**
     * 两个字符串相等
     * @param s1
     * @param s2
     * @return
     */
    public static boolean strEq(String s1, String s2){
        return (s1 != null && s1.equals(s2));
    }

    /**
     * 多个字符串拼接
     * @param values
     * @return
     */
    public static String stringSplicing(String ... values){
        if(values != null && values.length > 0){
            StringBuilder str = new StringBuilder();
            for(String value : values){
                str.append(value);
            }
            return str.toString();
        }
        return null;
    }

    /**
     * BufferedImage转字节数组
     * @param image
     * @return
     */
    public static byte[] bufferedImageToBytes(BufferedImage image){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            ImageIO.write(image,"jpg", baos);
            return baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            Tools.closeOutputIO(baos);
        }

        return null;
    }

    /**
     * 根据序列号获取设备信息
     * @param serialId
     * @return
     */
    public static DeviceBean getDeviceInfo(String serialId){
        List<DeviceBean> devices = getDevices();

        if(devices == null || devices.size() == 0){
            return null;
        }

        for(DeviceBean device : devices){
            if(strEq(serialId, device.getSerialNumber())){
                return device;
            }
        }

        return null;
    }

    /**
     * 读取设备配置信息
     * @return
     */
    public static List<DeviceBean> getDevices(){
        List<DeviceBean> devices = null;
        try{
            String filePath = stringSplicing(System.getProperty("user.dir").replaceAll("\\\\", "/"), "/db/device_data.json");
            String res = FileUtil.readString(filePath, "UTF-8");
            devices = JSONObject.parseArray(res, DeviceBean.class);
        } catch (Exception e){
            log.error("设备配置文件读取失败：{}", e.getMessage());
        }

        return devices;
    }

    /**
     * 备份配置数据
     * @return
     */
    public static boolean bakDevices(){
        boolean flag = false;
        List<DeviceBean> devices = Tools.getDevices();
        if(devices != null && devices.size() > 0){
            String filePath = System.getProperty("user.dir").replaceAll("\\\\", "/") + "/db/device_data.bak";
            FileUtil.writeString(JSON.toJSONString(devices), new File(filePath), "UTF-8");
            flag = true;
        }
        return flag;
    }

    /**
     * 将指定文件转换为字节数组
     * @param file
     * @return
     * @throws IOException
     */
    public static byte[] getFileIO(File file){
        byte[] imgData = null;
        try{
            if(file.exists()){
                //获取文件流
                FileInputStream fis = new FileInputStream(file);
                BufferedInputStream bis = new BufferedInputStream(fis);

                ByteArrayOutputStream baos = new ByteArrayOutputStream();

                byte[] bt = new byte[2048];
                int len = 0;
                while ((len = bis.read(bt)) != -1) {
                    baos.write(bt, 0, len);
                }

                imgData = baos.toByteArray();
                System.out.println(baos.toByteArray().length);

                closeOutputIO(baos);
                closeInputIO(bis);
                closeInputIO(fis);
            }
        } catch (IOException e){
            e.printStackTrace();
        }

        return imgData;
    }

    /**
     * 将字节流转换为图片并保存到服务本地
     * @param data
     * @param fileType
     * @param fileName 必须带后缀：图片.png、音频.mp3、视频.mp4
     */
    public static String byteToFile(byte[] data, FileType fileType, String fileName, boolean append){
        String imgUrl = getOS_ImgUrl(fileType);
        File file = new File(imgUrl);
        if(!file.exists()){
            file.mkdirs();
        }
        FileOutputStream fos = null;
        try {
            imgUrl += "/"+ fileName;
            fos = new FileOutputStream(imgUrl, append);
            fos.write(data);
            return imgUrl;
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            closeOutputIO(fos);
        }
        return "";
    }

    /**
     * 获取操作系统对应文件存储默认路径
     * @return
     */
    public static String getOS_ImgUrl(FileType type){
        String osName = System.getProperty("os.name");
        String path = Pattern.matches("Linux.*", osName) ? "/home" : DiskTools.getDriveLetter();
        switch (type) {
            case IMAGE:
                path += "/motorcycle/image/"+ DateUtil.format(new Date(), "yyyy-MM-dd");
                break;
            case CARD_IMAGE:
                path += "/motorcycle/idCardImage/"+DateUtil.format(new Date(), "yyyy-MM-dd");
                break;
            case AUDIO:
                path += "/motorcycle/audio/"+DateUtil.format(new Date(), "yyyy-MM-dd");
                break;
            case ITEM_AUDIO:
                path += "/motorcycle/itemAudio/"+DateUtil.format(new Date(), "yyyy-MM-dd");
                break;
            case VIDEO:
                path += "/motorcycle/video/"+DateUtil.format(new Date(), "yyyy-MM-dd");
                break;
            default:
                path += "/motorcycle/otherFile/"+DateUtil.format(new Date(), "yyyy-MM-dd");
                break;
        }
        File file = new File(path);
        if(!file.exists()){
            file.mkdirs();
        }
        return path;
    }

    /**
     * 密码加密
     * @param password
     * @return
     */
    public static String encryption(String password) {
        String result = password + ENCRYPT_KEY;
        String re_md5 = new String();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(result.getBytes());
            byte b[] = md.digest();

            int i;

            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0) {
                    i += 256;
                }
                if (i < 16) {
                    buf.append("0");
                }
                buf.append(Integer.toHexString(i));
            }

            re_md5 = buf.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return re_md5.toUpperCase();
    }

    /**
     * 关闭输入流
     * @param in
     */
    public static void closeInputIO(InputStream in){
        if(null != in){
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭输出流
     * @param os
     */
    public static void closeOutputIO(OutputStream os){
        if(null != os){
            try {
                os.flush();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取服务器IP
     * @return
     */
    public static String getLocalHostIP(){
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return "";
    }
}
